package com.winit.openapi.ece.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.winit.common.query.Page;
import com.winit.common.query.Searchable;
import com.winit.common.query.Sort;
import com.winit.common.query.Sort.Direction;
import com.winit.common.spi.command.GetByKeyCommand;
import com.winit.common.spi.context.CommandContext;
import com.winit.erp.spi.bpartner.ContractService;
import com.winit.erp.spi.bpartner.command.ContractCommand;
import com.winit.oms.spi.ece.EceOrderService;
import com.winit.oms.spi.ece.command.EceCommitOrderCommand;
import com.winit.oms.spi.ece.command.EceOrderBatchOptCommand;
import com.winit.oms.spi.ece.command.EceOrderSearchCommand;
import com.winit.oms.spi.ece.vo.EceMerchandiseVo;
import com.winit.oms.spi.ece.vo.EceOrderExpressInfoVo;
import com.winit.oms.spi.ece.vo.EceOrderInsuranceInfoVo;
import com.winit.oms.spi.ece.vo.EceOrderPackageVo;
import com.winit.oms.spi.ece.vo.EceOrderVo;
import com.winit.oms.spi.isp.common.EnumOrderType;
import com.winit.oms.spi.vo.BatchOptResult;
import com.winit.openapi.constants.ApiConstant;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.controller.BaseController;
import com.winit.openapi.ece.utils.EceOrderBuilder;
import com.winit.openapi.ece.utils.EceOrderfieldValidator;
import com.winit.openapi.exception.ApiException;
import com.winit.openapi.isp.status.EnumISPOrderStatus;
import com.winit.openapi.model.RequestMsg;
import com.winit.openapi.model.ResponseMsg;
import com.winit.openapi.util.DateUtil;
import com.winit.openapi.util.ValidateUtil;
import com.winit.vms.spi.EceOrderInsuranceInfoService;
import com.winit.vms.spi.command.EceOrderInsuranceInfoCommand;

/**
 * 进口订单页面交互入口
 * 
 * @version <pre>
 * Author   Version     Date        Changes
 * fei.liu  1.0         2015年8月3日   Created
 *
 * </pre>
 * @since 1.
 */
@Controller
@RequestMapping(value = "/ece/order")
public class EceOrderController extends BaseController {

    @Resource
    private ContractService     agreementService;

    private static final String ISP_BUSINESS_TYPE = "ISP";

    @Resource
    private EceOrderService     eceOrderService;
    @Resource
    private EceOrderInsuranceInfoService     eceOrderInsuranceInfoService;

    /**
     * 导入ece订单
     * 
     * @param requestMsg 页面请求对象
     * @param responseMsg 后台响应实体
     * @return 是否成功标志
     */
    @RequestMapping(value = "/importOrder")
    public String importOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 检查用户权限，无权限是方法内部抛异常
        checkUserRight(ISP_BUSINESS_TYPE);

        Object obj = requestMsg.getData();

        List<EceOrderVo> orderList = new ArrayList<EceOrderVo>();

        if (obj instanceof JSONObject) {
            JSONObject jsonObj = (JSONObject) obj;
            if (jsonObj.containsKey("orderList")) {
                JSONArray orderJsonList = jsonObj.getJSONArray("orderList");
                for (int i = 0; i < orderJsonList.size(); i++) {
                    JSONObject json = orderJsonList.getJSONObject(i);
                    // 校验参数(长度，非空等简单校验)
                    EceOrderfieldValidator.validOrderField(json);
                    EceOrderVo order = EceOrderBuilder.buildEceOrder(json);
                    orderList.add(order);
                }
            } else {
                throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
            }
        }
        // 组装command
        EceOrderBatchOptCommand command = new EceOrderBatchOptCommand();
        command.setCtx(CommandContext.getContext());
        command.setOrderList(orderList);
        // 调用接口创建订单
        Map<String, Object> result = (Map<String, Object>) eceOrderService.batchCreate(command);
        // Map<String, Object> data = new HashMap<String, Object>();
        // data.put("successCount", result.getSuccessCount());
        // data.put("failedCount", result.getFailedCount());
        // data.put("line", result.getLine());
        // data.put("errMsg", result.getErrMsg());
        responseMsg.setData(result);
        return SUCCESS;
    }

    /**
     * 批量更新ISP进口订单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/updateOrder")
    public String updateOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 效验用户是否是isp业务用户
        checkIspRight();
        Object obj = requestMsg.getData();
        List<EceOrderVo> orderList = new ArrayList<EceOrderVo>();
        Map<String, Object> data = new HashMap<String, Object>();
        if (obj instanceof JSONObject) {
            JSONObject jsonObj = (JSONObject) obj;
            if (null != jsonObj.get("orderList")) {
                JSONArray arrays = jsonObj.getJSONArray("orderList");
                for (int i = 0; i < arrays.size(); i++) {
                    JSONObject json = arrays.getJSONObject(i);
                    EceOrderfieldValidator.validOrderField(json);
                    EceOrderfieldValidator.validOrderNoField(json);
                    EceOrderVo eceOrderVo = EceOrderBuilder.buildEceOrder(json);
                    orderList.add(eceOrderVo);
                }
            } else {
                throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }

        EceOrderBatchOptCommand command = new EceOrderBatchOptCommand();
        command.setOrderList(orderList);
        command.setCtx(CommandContext.getContext());

        // 批量修改只返回成功数量，错误数量，不返回错误信息
        BatchOptResult result = eceOrderService.batchUpdate(command);
        data.put("successCount", result.getSuccessCount());
        data.put("failedCount", result.getFailedCount());
        responseMsg.setData(data);
        return SUCCESS;
    }

    /**
     * 批量提交ISP未提交订单列表中的校验异常订单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/commit")
    public String commit(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        EceCommitOrderCommand command = null;
        Object obj = requestMsg.getData();
        Map<String, Object> data = new HashMap<String, Object>();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            if (null != json.get("orderNoList")) {
                JSONArray arrays = json.getJSONArray("orderNoList");
                // 组装command
                command = buildCommitCommand(arrays);
                command.setCtx(CommandContext.getContext());
            } else {
                throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }

        BatchOptResult result = eceOrderService.batchCommit(command);
        if (result != null) {
            data.put("successCount", result.getSuccessCount());
            data.put("failedCount", result.getFailedCount());
            data.put("errorMsg", result.getErrMsg());
            responseMsg.setData(data);
        }
        return SUCCESS;
    }

    /**
     * 封装批量提交校验异常订单命令
     * 
     * @param json
     * @return
     */
    private EceCommitOrderCommand buildCommitCommand(JSONArray arrays) {
        EceCommitOrderCommand command = new EceCommitOrderCommand();
        List<String> orderNolist = new ArrayList<String>();
        if (arrays != null && !arrays.isEmpty()) {
            for (Object obj : arrays) {
                JSONObject str = (JSONObject) obj;
                EceOrderfieldValidator.validOrderNoField(str);
                orderNolist.add(str.getString("orderNo"));
            }
        }
        command.setOrderNolist(orderNolist);
        return command;
    }

    /**
     * 更新订单保险状态
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/updateInsuranceStatus")
    public String updateInsuranceStatus(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {

        Object obj = requestMsg.getData();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            EceOrderfieldValidator.validateInsuranceStatusField(json);
            EceOrderInsuranceInfoCommand command = new EceOrderInsuranceInfoCommand();
            EceOrderInsuranceInfoVo vo = EceOrderBuilder.buildEceOrderInsuranceInfoVo(json);
            command.setEceOrderInsuranceInfoVo(vo);
            command.setCtx(CommandContext.getContext());
            eceOrderInsuranceInfoService.updateEceOrderInsuranceStatus(command);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        return SUCCESS;
    }
    /**
     * 效验用户是不是isp用户 TODO Add comments here.
     */
    private void checkIspRight() {
        ContractCommand command = new ContractCommand();
        command.setBusiType("ISP");
        command.setBpartnerId(Long.parseLong(CommandContext.getContext().getUserId()));
        boolean rightStatus = agreementService.isOpenContract(command);

        if (!rightStatus) {
            throw new ApiException(ErrorCode.USERNAME_ISNOT_ISP_USER);
        }
    }

    /**
     * 查询订单列表以及导出
     * 
     * @param requestMsg 页面请求对象
     * @param responseMsg 后台响应实体
     * @return 是否成功标志
     */
    @RequestMapping(value = "/list")
    public String list(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 效验用户是否是isp业务用户
        checkIspRight();
        Object obj = requestMsg.getData();

        EceOrderSearchCommand command = null;

        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            validSearchECEOrder(json);
            command = buildSearchOrderCommand(json);
            Searchable searchable = buildSearchPageParams(json);
            command.setSearchable(searchable);
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());

        // 调用接口分页查询订单
        Page<EceOrderVo> pagelist = eceOrderService.getEceOrderList(command);
        if (pagelist != null) {
            List<Map<String, Object>> datalist = buildReturnEceOrderList(pagelist.getContent(),
                command.getExprotErrMsg());

            Map<String, Object> pageMap = new HashMap<String, Object>();
            pageMap.put("pageNo", pagelist.getPageable().getPageNumber());
            pageMap.put("pageSize", pagelist.getPageable().getPageSize());
            pageMap.put("totalCount", pagelist.getTotalElements());

            Map<String, Object> data = new HashMap<String, Object>();
            data.put("list", datalist);
            data.put("pageParams", pageMap);
            responseMsg.setData(data);
        }
        return SUCCESS;
    }

    /**
     * 查询订单详情
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/query")
    public String query(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 效验用户是否是isp业务用户
        checkIspRight();
        Object obj = requestMsg.getData();

        GetByKeyCommand<String> command = new GetByKeyCommand<String>();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            validOrderNo(json);
            command.setSearchKey(json.getString("orderNo"));
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }
        command.setCtx(CommandContext.getContext());
        // 调用接口查询订单
        EceOrderVo order = eceOrderService.getEceOrderByNo(command);
        if (order != null) {
            Map<String, Object> map = buildReturnEceOrderInfo(order);
            responseMsg.setData(map);
        } else {
            throw new ApiException(ErrorCode.FIELD_ISPORDERNO_NOT_EXIST);
        }
        return SUCCESS;
    }

    private void validOrderNo(JSONObject json) {
        // orderNo
        ValidateUtil.validNotNull(json, "orderNo");
        ValidateUtil.validMaxLength(json, "orderNo", 60);
    }

    private EceOrderSearchCommand buildSearchOrderCommand(JSONObject json) {
        EceOrderSearchCommand command = new EceOrderSearchCommand();
        // orderNo
        if (json.containsKey("orderNo")) {
            command.setOrderNo(json.getString("orderNo"));
        }
        // trackingNo
        if (json.containsKey("trackingNo")) {
            command.setExpressNo(json.getString("trackingNo"));
            ;
        }
        // paymentTransactionId
        if (json.containsKey("paymentTransactionId")) {
            command.setPaymentTransactionId(json.getString("paymentTransactionId"));
        }
        // refNo
        if (json.containsKey("refNo")) {
            command.setSellerOrderNo(json.getString("refNo"));
        }
        // buyerName
        if (json.containsKey("buyerName")) {
            command.setBuyerFullname(json.getString("buyerName"));
        }
        // warehouseCode
        if (json.containsKey("warehouseCode")) {
            command.setWarehouseCode(json.getString("warehouseCode"));
        }
        // winitProductCode
        if (json.containsKey("winitProductCode")) {
            command.setWinitProductName(json.getString("winitProductCode"));
        }
        // winitProductName
        if (json.containsKey("winitProductName")) {
            command.setWinitProductName(json.getString("winitProductName"));
        }
        // winitProductCode
        if (json.containsKey("exportErrMsg")) {
            command.setExprotErrMsg(json.getString("exportErrMsg"));
        }

        if (isExistValue(json, "orderType")) {
            if ("3".equals(json.getString("orderType"))) command.setType(EnumOrderType.UNBOUND);
            if ("2".equals(json.getString("orderType"))) command.setType(EnumOrderType.ALL);
            if ("1".equals(json.getString("orderType"))) command.setType(EnumOrderType.NORM);
            if ("0".equals(json.getString("orderType"))) command.setType(EnumOrderType.EX);
        }
        // status
        if (json.containsKey("status")) {
            if (StringUtils.isNotBlank(json.getString("status"))) {
                String[] arr = json.getString("status").split(",");
                command.setStatus(Arrays.asList(arr));
            }
        }

        // orderDateStart
        if (json.containsKey("orderDateStart")) {
            String orderDateStart = json.getString("orderDateStart");
            orderDateStart += " 00:00:00";
            Date from = DateUtil.parse2Date(orderDateStart, DateUtil.FULL_DATE_STRING);
            command.setDateFrom(from);
        }
        // orderDateEnd
        if (json.containsKey("orderDateEnd")) {
            String orderDateEnd = json.getString("orderDateEnd");
            orderDateEnd += " 23:59:59";
            Date to = DateUtil.parse2Date(orderDateEnd, DateUtil.FULL_DATE_STRING);
            command.setDateTo(to);
        }

        return command;
    }

    /**
     * 组装查询订单详情返回参数
     * 
     * @param order
     * @param orderType
     * @return
     */
    private Map<String, Object> buildReturnEceOrderInfo(EceOrderVo order) {
        Map<String, Object> map = new HashMap<String, Object>();
        /************************** order ***********************/
        map.put("orderNo", order.getOrderNo());
        map.put("refNo", order.getSellerOrderNo());
        map.put("paymentTransactionId", order.getPaymentTransactionId());
        map.put("winitProductCode", order.getWinitProductCode());
        map.put("winitProductName", order.getWinitProductName());
        map.put("isValid", EnumISPOrderStatus.PD.getStatus().equals(order.getStatus()) ? "N" : "Y");
        map.put("errMsg", order.getErrMsg());
        String orderDate = DateUtil.parse2String(order.getOrderDate(), DateUtil.FULL_DATE_STRING);
        map.put("orderDate", orderDate);
        map.put("status", order.getStatus());
        map.put("dispatchType", order.getDispatchType());
        /************************* buyer ************************/
        map.put("buyerCitizenIdNo", order.getBuyerCitizenIdNo());
        map.put("buyerName", order.getBuyerFullname());
        map.put("buyerContactNo", order.getBuyerContactNumber());
        map.put("buyerEmail", order.getBuyerEmail());
        map.put("buyerZipCode", order.getBuyerPostcode());
        map.put("buyerCountry", order.getBuyerCountry());
        map.put("buyerCountryCode", order.getBuyerCountryCode());
        map.put("buyerState", order.getBuyerState());
        map.put("buyerCity", order.getBuyerCity());
        map.put("buyerDistrict", order.getBuyerDistrict());
        map.put("buyerAddress1", order.getBuyerAddress1());
        map.put("buyerAddress2", order.getBuyerAddress2());
        map.put("buyerHouseNo", order.getHouseNo());

        /*********************** shipper ************************/
        map.put("shipperAddrCode", order.getShipperAddrCode());
        map.put("shipperCountry", order.getShipperCountry());
        map.put("shipperCountryCode", order.getShipperCountryCode());
        map.put("shipperState", order.getShipperState());
        map.put("shipperCity", order.getShipperCity());
        map.put("shipperDistrict", order.getShipperDistrict());
        map.put("shipperPostCode", order.getShipperPostcode());
        map.put("shipperAddress1", order.getShipperAddress1());
        map.put("shipperAddress2", order.getShipperAddress2());
        map.put("shipperEmail", order.getShipperEmail());
        map.put("ebaySellerId", order.getEbaySellerId());
        map.put("totalAmount", order.getTotalAmount());
        map.put("currency", order.getCurrency());
        /************* 仓库 *************/
        map.put("warehouseName", order.getInspectionWarehouseName());
        map.put("warehouseCode", order.getInspectionWarehouseCode());

        /************* 是否需要保险 *************/
        map.put("isInsure", order.getIsInsure());
        /************* 税金 *************/
        map.put("taxes", order.getTaxes());
        /************* 运费 *************/
        map.put("freight", order.getFreight());
        /************* 货款 *************/
        map.put("goodsAmount", order.getGoodsAmount());

        Map<String, Object> orderExpressMap = null;
        List<Map<String, Object>> expressList = new ArrayList<Map<String, Object>>();
        List<EceOrderExpressInfoVo> orderExpressList = order.getExpressNoList();
        if (orderExpressList != null) {
            for (EceOrderExpressInfoVo orderExpress : orderExpressList) {
                orderExpressMap = new HashMap<String, Object>();
                orderExpressMap.put("expressNo", orderExpress.getExpressNo());
                orderExpressMap.put("status", orderExpress.getStatus());
                expressList.add(orderExpressMap);
            }

            map.put("expressList", expressList);
        }

        List<Map<String, Object>> olList = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> mlList = new ArrayList<Map<String, Object>>();
        Map<String, Object> orderLineMap = null;
        Map<String, Object> merchandiseMap = null;
        List<EceOrderPackageVo> orderPackageList = order.getOrderPackageList();
        if (orderPackageList != null) {
            for (EceOrderPackageVo orderPackage : orderPackageList) {
                /*********************** package ************************/
                orderLineMap = new HashMap<String, Object>();
                /*
                 * orderLineMap.put("weight", orderPackage.getGrossWeight());
                 * orderLineMap.put("length", orderPackage.getLength());
                 * orderLineMap.put("width", orderPackage.getWidth());
                 * orderLineMap.put("height", orderPackage.getHeight());
                 */
                orderLineMap.put("weight", orderPackage.getCfmGrossWeight());
                orderLineMap.put("length", orderPackage.getCfmLength());
                orderLineMap.put("width", orderPackage.getCfmWidth());
                orderLineMap.put("height", orderPackage.getCfmHeight());
                orderLineMap.put("labelNo", orderPackage.getLabelNo());
                orderLineMap.put("trackingNo", orderPackage.getTrackingNo());

                List<EceMerchandiseVo> merchandiseList = orderPackage.getMerchandiseList();
                if (merchandiseList != null && merchandiseList.size() > 0) {
                    for (EceMerchandiseVo m : merchandiseList) {
                        merchandiseMap = new HashMap<String, Object>();
                        merchandiseMap.put("productCode", m.getMerchandiseCode());
                        merchandiseMap.put("productNameCn", m.getMerchandiseNameCn());
                        merchandiseMap.put("productNameEn", m.getMerchandiseNameEn());
                        merchandiseMap.put("specification", m.getMerchandiseSpecification());
                        merchandiseMap.put("brandName", m.getBrandName());
                        merchandiseMap.put("extraGift", m.getExtraGift());
                        merchandiseMap.put("quantity", m.getMerchandiseQuantity());
                        merchandiseMap.put("salePrice", m.getSalePrice());
                        merchandiseMap.put("currency", m.getCurrencyCode());
                        mlList.add(merchandiseMap);
                    }
                }
                orderLineMap.put("merchandiseList", mlList);
                olList.add(orderLineMap);
            }
            map.put("packageList", olList);
        }
        return map;

    }

    private List<Map<String, Object>> buildReturnEceOrderList(List<EceOrderVo> datalist, String orderType) {
        List<Map<String, Object>> rslist = new ArrayList<Map<String, Object>>();
        Map<String, Object> map = null;
        for (EceOrderVo order : datalist) {
            map = buildReturnEceOrder(order, orderType);
            rslist.add(map);
        }
        return rslist;
    }

    private Searchable buildSearchPageParams(JSONObject json) {
        int pageNo = ApiConstant.PAGE_NO_DEFAULT;
        int pageSize = ApiConstant.PAGE_SIZE_DEFAULT;
        // pageParams
        if (isExistValue(json, "pageParams")) {
            JSONObject pageParams = json.getJSONObject("pageParams");

            if (ValidateUtil.isIntNumber(pageParams.getString("pageNo"))) {
                pageNo = pageParams.getInteger("pageNo");
                if (pageNo <= 0) {
                    throw new ApiException(ErrorCode.FIELD_ERROR, "pageNo");
                }
            } else if (isExistValue(pageParams, "pageNo") && !ValidateUtil.isIntNumber(pageParams.getString("pageNo"))) {
                throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "pageNo");
            }

            if (ValidateUtil.isIntNumber(pageParams.getString("pageSize"))) {
                pageSize = pageParams.getInteger("pageSize");
                if (pageSize <= 0) {
                    throw new ApiException(ErrorCode.FIELD_ERROR, "pageSize");
                }
            } else if (isExistValue(pageParams, "pageSize")
                       && !ValidateUtil.isIntNumber(pageParams.getString("pageSize"))) {
                throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "pageSize");
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "pageParams");
        }
        Searchable search = Searchable.newSearchable();
        search.setPage(pageNo, pageSize);

        search.addSort(new Sort(Direction.DESC, "CREATED"));

        return search;
    }

    private Map<String, Object> buildReturnEceOrder(EceOrderVo order, String orderType) {
        Map<String, Object> map = new HashMap<String, Object>();
        List<EceOrderPackageVo> eceOrderPackageList = order.getOrderPackageList();
        /************************** order ***********************/
        map.put("orderNo", order.getOrderNo());
        map.put("refNo", order.getSellerOrderNo());
        map.put("paymentTransactionId", order.getPaymentTransactionId());
        map.put("winitProductCode", order.getWinitProductCode());
        map.put("winitProductName", order.getWinitProductName());
        map.put("isValid", EnumISPOrderStatus.PD.getStatus().equals(order.getStatus()) ? "N" : "Y");
        map.put("errMsg", order.getErrMsg());
        String orderDate = DateUtil.parse2String(order.getOrderDate(), DateUtil.FULL_DATE_STRING);
        map.put("orderDate", orderDate);
        map.put("status", order.getStatus());
        map.put("totalAmount", order.getTotalAmount());
        map.put("currency", order.getCurrency());
        map.put("buyerCitizenIdNo", order.getBuyerCitizenIdNo());
        map.put("shipperAddrCode", order.getShipperAddrCode());
        map.put("dispatchType", order.getDispatchType());
        /************************* buyer ************************/
        map.put("buyerName", order.getBuyerFullname());
        map.put("buyerContactNo", order.getBuyerContactNumber());
        map.put("buyerEmail", order.getBuyerEmail());
        map.put("buyerZipCode", order.getBuyerPostcode());
        map.put("buyerCountry", order.getBuyerCountryCode());
        map.put("buyerCountryCode", order.getBuyerCountryCode());
        map.put("buyerState", order.getBuyerState());
        map.put("buyerCity", order.getBuyerCity());
        map.put("buyerDistrict", order.getBuyerDistrict());
        map.put("buyerAddress1", order.getBuyerAddress1());
        map.put("buyerAddress2", order.getBuyerAddress2());
        map.put("buyerHouseNo", order.getHouseNo());

        /*********************** shipper ************************/
        map.put("shipperAddrCode", order.getShipperAddrCode());
        map.put("shipperCountry", order.getShipperCountry());
        map.put("shipperCountryCode", order.getShipperCountryCode());
        map.put("shipperState", order.getShipperState());
        map.put("shipperCity", order.getShipperCity());
        map.put("shipperDistrict", order.getShipperDistrict());
        map.put("shipperPostCode", order.getShipperPostcode());
        map.put("shipperAddress1", order.getShipperAddress1());
        map.put("shipperAddress2", order.getShipperAddress2());
        map.put("shipperEmail", order.getShipperEmail());
        map.put("ebaySellerId", order.getEbaySellerId());
        /************* 仓库 *************/
        map.put("warehouseName", order.getInspectionWarehouseName());
        map.put("warehouseCode", order.getInspectionWarehouseCode());

        /************* 是否需要保险 *************/
        map.put("isInsure", order.getIsInsure());
        /************* 税金 *************/
        map.put("taxes", order.getTaxes());
        /************* 运费 *************/
        map.put("freight", order.getFreight());
        /************* 货款 *************/
        map.put("goodsAmount", order.getGoodsAmount());

        /************* 快递信息 *************/
        Map<String, Object> orderExpressMap = null;
        List<Map<String, Object>> expressList = new ArrayList<Map<String, Object>>();
        List<EceOrderExpressInfoVo> orderExpressList = order.getExpressNoList();
        if (orderExpressList != null) {
            for (EceOrderExpressInfoVo orderExpress : orderExpressList) {
                orderExpressMap = new HashMap<String, Object>();
                orderExpressMap.put("expressNo", orderExpress.getExpressNo());
                orderExpressMap.put("status", orderExpress.getStatus());
                expressList.add(orderExpressMap);
            }

            map.put("expressList", expressList);
        }

        List<Map<String, Object>> olList = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> mlList = new ArrayList<Map<String, Object>>();
        Map<String, Object> orderLineMap = null;
        Map<String, Object> merchandiseMap = null;

        if (eceOrderPackageList != null) {
            for (int i = 0; i < eceOrderPackageList.size(); i++) {
                /*********************** package ************************/
                orderLineMap = new HashMap<String, Object>();
                orderLineMap.put("weight", eceOrderPackageList.get(i).getGrossWeight());
                orderLineMap.put("length", eceOrderPackageList.get(i).getLength());
                orderLineMap.put("width", eceOrderPackageList.get(i).getWidth());
                orderLineMap.put("height", eceOrderPackageList.get(i).getHeight());
                orderLineMap.put("labelNo", eceOrderPackageList.get(i).getLabelNo());
                orderLineMap.put("trackingNo", eceOrderPackageList.get(i).getTrackingNo());

                List<EceMerchandiseVo> merchandiseList = eceOrderPackageList.get(i).getMerchandiseList();
                if (merchandiseList != null && merchandiseList.size() > 0) {
                    for (EceMerchandiseVo m : merchandiseList) {
                        merchandiseMap = new HashMap<String, Object>();
                        merchandiseMap.put("productCode", m.getMerchandiseCode());
                        merchandiseMap.put("productNameCn", m.getMerchandiseNameCn());
                        merchandiseMap.put("productNameEn", m.getMerchandiseNameEn());
                        merchandiseMap.put("specification", m.getMerchandiseSpecification());
                        merchandiseMap.put("brandName", m.getBrandName());
                        merchandiseMap.put("extraGift", m.getExtraGift());
                        merchandiseMap.put("quantity", m.getMerchandiseQuantity());
                        merchandiseMap.put("salePrice", m.getSalePrice());
                        merchandiseMap.put("currency", m.getCurrencyCode());
                        mlList.add(merchandiseMap);
                    }
                }
                orderLineMap.put("merchandiseList", mlList);
                olList.add(orderLineMap);
            }
            map.put("orderPackageList", olList);
        }
        return map;
    }

    private void validSearchECEOrder(JSONObject json) {
        // orderNo
        ValidateUtil.validMaxLength(json, "orderNo", 60);
        // refNo
        ValidateUtil.validMaxLength(json, "refNo", 60);
        // buyerName
        ValidateUtil.validMaxLength(json, "buyerName", 50);
        // paymentTransactionId
        ValidateUtil.validMaxLength(json, "paymentTransactionId", 32);
        // warehouseCode
        ValidateUtil.validMaxLength(json, "warehouseCode", 60);
        // winitProductCode
        ValidateUtil.validMaxLength(json, "winitProductCode", 50);
        // status
        ValidateUtil.validMaxLength(json, "status", 50);
        // orderDateStart
        ValidateUtil.validDateString(json, "orderDateStart", DateUtil.SIMPLE_DATE_STRING);
        // orderDateEnd
        ValidateUtil.validDateString(json, "orderDateEnd", DateUtil.SIMPLE_DATE_STRING);
        ValidateUtil.validDateBefore(json, "orderDateStart", "orderDateEnd");

        // pageParams
        if (json.containsKey("pageParams")) {
            Object obj = json.get("pageParams");
            if (obj instanceof JSONObject) {
                JSONObject pageParams = (JSONObject) obj;

                if (isExistValue(pageParams, "pageNo")) {
                    // pageNo
                    ValidateUtil.validInteger(pageParams, "pageNo");

                    int pageNo = pageParams.getInteger("pageNo");
                    if (pageNo < 1) {
                        throw new ApiException(ErrorCode.FIELD_ERROR, "pageNo");
                    }
                } else if (!isExistValue(pageParams, "pageNo")) {
                    throw new ApiException(ErrorCode.FIELD_NOT_NULL, "pageNo");
                }

                if (isExistValue(pageParams, "pageSize")) {
                    // pageSize
                    ValidateUtil.validInteger(pageParams, "pageSize");

                    int pageSize = pageParams.getInteger("pageSize");
                    if (pageSize < 1) {
                        throw new ApiException(ErrorCode.FIELD_ERROR, "pageSize");
                    }
                    if (pageSize > 2000) {
                        throw new ApiException(ErrorCode.FIELD_ERROR, "pageSize");
                    }
                } else if (!isExistValue(pageParams, "pageSize")) {
                    throw new ApiException(ErrorCode.FIELD_NOT_NULL, "pageSize");
                }
            } else {
                throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "pageParams");
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_NOT_NULL, "pageParams");
        }
    }

    // 判断非必填字段是否有值
    public boolean isExistValue(JSONObject jsonObject, String key) {
        if (jsonObject.containsKey(key)) {
            return !"".equals(jsonObject.getString(key).trim());
        }
        return false;
    }

    /**
     * 作废ECE订单
     * 
     * @param requestMsg
     * @param responseMsg
     * @return
     */
    @RequestMapping(value = "/void")
    public String voidEceOrder(@ModelAttribute RequestMsg requestMsg, @ModelAttribute ResponseMsg responseMsg) {
        // 效验用户是否是isp业务用户
        checkUserRight(ISP_BUSINESS_TYPE);
        Object obj = requestMsg.getData();

        List<EceOrderVo> orderList = new ArrayList<EceOrderVo>();
        if (obj instanceof JSONObject) {
            JSONObject json = (JSONObject) obj;
            JSONArray orderArrjson = null;
            if (null != json.get("orderNoList") && json.get("orderNoList") instanceof JSONArray) {
                orderArrjson = (JSONArray) json.get("orderNoList");
                for (int i = 0; i < orderArrjson.size(); i++) {
                    JSONObject orderNojson = orderArrjson.getJSONObject(i);
                    // 校验参数
                    EceOrderfieldValidator.validOrderNoField(orderNojson);
                    EceOrderVo vo = new EceOrderVo();
                    vo.setOrderNo(orderNojson.getString("orderNo"));
                    orderList.add(vo);
                }
            } else {
                throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
            }
        } else {
            throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
        }

        // 组装command
        EceOrderBatchOptCommand command = new EceOrderBatchOptCommand();
        command.setCtx(CommandContext.getContext());
        command.setOrderList(orderList);
        // 调用接口作废订单
        BatchOptResult result = eceOrderService.batchVoidOrder(command);

        Map<String, Object> data = new HashMap<String, Object>();
        data.put("successCount", result.getSuccessCount());
        data.put("failedCount", result.getFailedCount());
        responseMsg.setData(data);

        return SUCCESS;
    }

    /**
     * 效验用户是否有开通业务
     * 
     * @param 待检查业务类型
     */
    public void checkUserRight(String businessType) {
        ContractCommand command = new ContractCommand();
        command.setBusiType(businessType);
        command.setBpartnerId(Long.parseLong(CommandContext.getContext().getUserId()));
        boolean rightStatus = agreementService.isOpenContract(command);

        if (!rightStatus) {
            throw new ApiException(ErrorCode.USERNAME_ISNOT_ISP_USER);
        }
    }

    /**
     * 批量导入ece订单 （兼容进口一期）
     * 
     * @param requestMsg 页面请求对象
     * @param responseMsg 后台响应实体
     * @return 是否成功标志
     */
    // @RequestMapping(value = "/batchCreateOrder")
    // public String batchCreateOrder(@ModelAttribute RequestMsg requestMsg,
    // @ModelAttribute ResponseMsg responseMsg) {
    // // 检查用户权限，无权限是方法内部抛异常
    // checkUserRight(ISP_BUSINESS_TYPE);
    // Object obj = requestMsg.getData();
    // List<EceOrderVo> orderList = new ArrayList<EceOrderVo>();
    //
    // if (obj instanceof JSONObject) {
    // JSONObject json = (JSONObject) obj;
    // EceOrderfieldValidator.validBatchImportOrder(json);
    // EceOrderVo eceOrder = EceOrderBuilder.buildISPImportOrder(json);
    // orderList.add(eceOrder);
    // } else {
    // throw new ApiException(ErrorCode.FIELD_TYPE_ERROR, "data");
    // }
    //
    // // 组装command
    // EceOrderBatchOptCommand command = new EceOrderBatchOptCommand();
    // command.setCtx(CommandContext.getContext());
    // command.setOrderList(orderList);
    //
    // // 调用接口创建订单
    // BatchOptResult result = eceOrderService.batchCreate(command);
    //
    // Map<String, Object> data = new HashMap<String, Object>();
    // data.put("successCount", result.getSuccessCount());
    // data.put("failedCount", result.getFailedCount());
    // responseMsg.setData(data);
    //
    // return SUCCESS;
    // }
}
